﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace PPSkin
{
    public static  class MemoryFontHelper
    {
        private static Dictionary<byte[], FontFamily> fontFamilies = new Dictionary<byte[], FontFamily>();

        [DllImport("gdi32.dll")]
        static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pvd, [In] ref uint pcFonts);

        /// <summary>
        /// 从字节数组中获取字体,可将字体文件转为字体
        /// </summary>
        /// <param name="fontData"></param>
        /// <returns></returns>
        public static FontFamily FontFamilyFromResources(byte[] fontData)
        {
            var pair = fontFamilies.FirstOrDefault(k => k.Key.SequenceEqual(fontData));
            if (pair.Value != null)
                return pair.Value;

            int dataLength = fontData.Length;
            IntPtr fontPtr = Marshal.AllocCoTaskMem(dataLength);
            Marshal.Copy(fontData, 0, fontPtr, dataLength);

            uint cFonts = 0;
            AddFontMemResourceEx(fontPtr, (uint)fontData.Length, IntPtr.Zero, ref cFonts);
            PrivateFontCollection collection = new PrivateFontCollection();
            collection.AddMemoryFont(fontPtr, dataLength);
            FontFamily fontFamily = collection.Families.First();
            fontFamilies.Add(fontData, fontFamily);
            collection.Dispose();
            return fontFamily;
        }

        /// <summary>
        /// 从内存中获取字体
        /// </summary>
        /// <param name="fontData"></param>
        /// <param name="size"></param>
        /// <param name="style"></param>
        /// <returns></returns>
        public static Font FontFromMemorey(byte[] fontData, float size, FontStyle style = FontStyle.Regular)
            => new Font(FontFamilyFromResources(fontData), size, style, GraphicsUnit.Point);
    }
}
